/*
 * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd.. 2023. All rights reserved.
 * Copyright (c) kidwjb
 * Description: sle uuid server sample,ADC value report to IOT cloud.
 */
#include "securec.h"
#include "errcode.h"
#include "osal_addr.h"
#include "soc_osal.h"
#include "app_init.h"
#include "sle_common.h"
#include "sle_errcode.h"
#include "sle_ssap_server.h"
#include "sle_connection_manager.h"
#include "sle_device_discovery.h"
#include "sle_server_adv.h"
#include "sle_server.h"
#include "cmsis_os2.h"
#include "pinctrl.h"
#include "adc.h"
#include "adc_porting.h"
#include "uart.h"
#include "common_def.h"
#include "tcxo.h"
#include <time.h>
#include <sys/time.h>

#define DELAY_1000MS 1000
#define CYCLES 10
#define OCTET_BIT_LEN 8
#define UUID_LEN_2 2
#define BT_INDEX_4 4
#define BT_INDEX_5 5
#define BT_INDEX_0 0
#define DELAY_5000MS 5000
#define CONFIG_UART_TXD_PIN                15
#define CONFIG_UART_RXD_PIN                16
#define CONFIG_UART_BUS_ID                 1
#define UART_BAUDRATE                      115200
#define UART_DATA_8BITS                    3
#define UART_STOP_BITS                     1
#define UART_PARITY_BIT                    0
#define UART_TRANSFER_SIZE                 512
#define MSG_QUEUE_NUMBER                   10

#define encode2byte_little(_ptr, data)                     \
    do {                                                   \
        *(uint8_t *)((_ptr) + 1) = (uint8_t)((data) >> 8); \
        *(uint8_t *)(_ptr) = (uint8_t)(data);              \
    } while (0)

enum {
    INDEX0,
    INDEX1,
    INDEX2,
    INDEX3,
    INDEX4,
    INDEX5,
    INDEX6,
    INDEX7,
    INDEX8,
    INDEX9,
    INDEX10,
    INDEX11,
    INDEX12,
    INDEX13,
    INDEX14,
    INDEX15,
};

//压力传感器按下状态
typedef enum {
    UNPRESSED, //未按下
    PRESSING,  //正在按下
    PRESSED,   //已按下
}pressStatus_t;

uint8_t g_app_uart_rx_buff[UART_TRANSFER_SIZE] = {0};
uint8_t command_read_epc_single[] = {0xBB ,0x00 ,0x22 ,0x00 ,0x00 ,0x22 ,0x7E};//单次轮询，芯片接收到单次轮询指令后，如果能够读到CRC校验正确的标签，芯片MCU将返回包含RSSI、PC、EPC
//和CRC的数据。读到一个标签EPC就返回一条指令响应，读到多个标签则返回多条指令响应
uint8_t get_tx_power[] = {0xBB,0x00,0xB7,0x00,0x00,0xB7,0x7E};
uint8_t set_tx_power[] = {0xBB,0x00,0xB6,0x00,0x02,0x00,0x00,0x00,0x7E};

osMessageQueueId_t MsgQueue_ID; // 消息队列的ID
uint8_t pressStatus = UNPRESSED;

typedef enum{
    READ_EPC_SINGLE = 1,
    READ_EPC_PLURAL = 2,
    STOP_READ_EPC_PLURAL = 3,
}command_t;

typedef struct 
{
    uint8_t data[120];
    uint16_t data_len;
}queue_structure_t;

queue_structure_t queue_input;
queue_structure_t queue_output;

typedef struct 
{
    uint8_t header;
    uint8_t type;
    uint8_t cammand;
    uint8_t PL[2];
    uint8_t rssi;
    uint8_t PC[2];
    uint8_t EPC[12];
    uint8_t crc[2];
    uint8_t checksum;
    uint8_t end;
}RFID_find_t;

/* sle server app uuid for test */
char g_sle_uuid_app_uuid[UUID_LEN_2] = {0x0, 0x0};
/* server notify property uuid for test */
char g_sle_property_value[OCTET_BIT_LEN] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
/* sle connect acb handle */
uint16_t g_sle_conn_hdl = 0;
/* sle server handle */
uint8_t g_server_id = 0;
/* sle service handle */
uint16_t g_service_handle = 0;
/* sle ntf property handle */
uint16_t g_property_handle = 0;

static uint8_t sle_uuid_base[] = {0x37, 0xBE, 0xA8, 0x80, 0xFC, 0x70, 0x11, 0xEA,
                                  0xB7, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

uint16_t voltage = 0;

//***************************sntp******************************//
void get_current_time(void)
{
    while (1) {
        struct timeval current_time;
        if (gettimeofday(&current_time, NULL) == -1) {
            osal_printk("gettimeofday FAIL\r\n");
        }
        time_t rawtime = current_time.tv_sec; // Get the time in seconds
        // Convert to local time
        struct tm *local_time;
        local_time = localtime(&rawtime);
        if (local_time == NULL) {
            printf("localtime failed\r\n");
            return;
        }
        // Print local time in YYYY-MM-DD format
        printf("Local time: %04d-%02d-%02d %02d:%02d:%02d\r\n",
               local_time->tm_year + 1900, // tm_year is years since 1900
               local_time->tm_mon + 1,     // tm_mon is months since January (0-11)
               local_time->tm_mday,        // Day of the month (1-31)
               local_time->tm_hour,        // Hour (0-23)
               local_time->tm_min,         // Minutes (0-59)
               local_time->tm_sec);        // Seconds (0-59)
        osal_msleep(DELAY_5000MS);
    }
}

void time_convert(time_t *rawtime, uint8_t *send_time)
{
    uint64_t temp = 0;
    uint8_t i = 0;
    for (i = 0; i < 8; i++) {                           /*8：一共八个字节*/
        temp |= (uint64_t)send_time[i] << (56 - i * 8); /*时间转换 一共56位，一次8位*/
    }
    *rawtime = (time_t)temp;
}
//---------------------------sntp------------------//

//***************************RFID***************************//
void Command_send(uint8_t *command,uint32_t length)
{
    uapi_uart_write(CONFIG_UART_BUS_ID,command,length,0);
}

void change_tx_power(uint16_t power_value)
{   
    uint8_t check_sum = 0;
    set_tx_power[5] = ((power_value >> 8) & 0x00ff);
    set_tx_power[6] = (power_value & 0x00ff);
    check_sum = 0x00 + 0xB6 + 0x00 + 0x02 + set_tx_power[5] + set_tx_power[6];
    set_tx_power[7] = check_sum;
    Command_send(set_tx_power,sizeof(set_tx_power));
}

static void *adc_task(const char *arg)
{
    unused(arg);
    osal_printk("start adc sample\r\n");
    uapi_adc_init(ADC_CLOCK_NONE);
    uint8_t adc_channel = ADC_CHANNEL_5;
    // uint8_t string_vol[30];
    while (1) {
        adc_port_read(adc_channel, &voltage);
        osal_printk("voltage: %d mv\r\n", voltage);
        osal_msleep(1000);
    }
    /* 当前测量的电压值和实际值可能有较大差别，请确认是否有分压电阻，如果有分压电阻，则差别符合预期 */
    uapi_adc_deinit();

    return NULL;
}

//*****************处理数据******************//
void pair_epc_num(uint8_t high,uint8_t low)
{
    uint8_t data[4] = {0xAA,0x66,0x00,0xFF};
    if(high == 0xAC && low == 0xC4)
    {
        osal_printk("find the label 1\r\n");
        data[INDEX2] = 0x01;
        sle_uuid_server_send_report_by_handle(data,sizeof(data));
    }
    else if(high == 0x8F && low == 0x96)
    {
        osal_printk("find the label 2\r\n");
        data[INDEX2] = 0x02;
        sle_uuid_server_send_report_by_handle(data,sizeof(data));
    }
    else if(high == 0xA7 && low == 0x44)
    {
        osal_printk("find the label 3\r\n");
        data[INDEX2] = 0x03;
        sle_uuid_server_send_report_by_handle(data,sizeof(data));
    }
    else if(high == 0x97 && low == 0x2C)
    {
        osal_printk("find the label 4\r\n");
        data[INDEX2] = 0x04;
        sle_uuid_server_send_report_by_handle(data,sizeof(data));
    }
    else if(high == 0x9F && low == 0xE8)
    {
        osal_printk("find the label 5\r\n");
        data[INDEX2] = 0x05;
        sle_uuid_server_send_report_by_handle(data,sizeof(data));
    }
}

void analyze_data(uint8_t *ptr)
{
    RFID_find_t find_data;
    memcpy_s(&find_data,sizeof(find_data),ptr,24);
    if(find_data.cammand == 0x22 && find_data.PL[0] == 0x00 && find_data.PL[1] == 0x11 
    && find_data.PC[0] == 0x34 && find_data.PC[1] == 0x00)
    {
        pair_epc_num(find_data.EPC[10],find_data.EPC[11]);
    }
}

void queue_deal_task(void)
{
    osStatus_t status = 0;
    uint8_t i  = 0;
    while(1)
    {
        status = osMessageQueueGet(MsgQueue_ID, &queue_output, 0, 0);
        if(status == osOK)
        {
           if(queue_output.data_len == 8)
           {
            osal_printk("No label find!!!\r\n");
           }
           else if(queue_output.data_len == 24)
           {
                analyze_data(queue_output.data);
           }
           else if(queue_output.data_len == 48)
           {
                for(i = 0;i < 2;i++)
                {
                    analyze_data(queue_output.data + i * 24);
                }
           }
           else if(queue_output.data_len == 72)
           {
                for(i = 0;i < 3;i++)
                {
                    analyze_data(queue_output.data + i * 24);
                }
           }
           else if(queue_output.data_len == 96)
           {
                for(i = 0;i < 4;i++)
                {
                    analyze_data(queue_output.data + i * 24);
                }
           }
           else if(queue_output.data_len == 120)
           {
                for(i = 0;i < 5;i++)
                {
                    analyze_data(queue_output.data + i * 24);
                }
           }
        }
        osal_msleep(500);//每500ms处理一次队列中的数据
    }
}

//-------------------------处理数据---------------------------//
//uart接收回调函数
void uart_rx_cbk(const void *buffer, uint16_t length, bool error)
{
    unused(length);
    unused(error);
    uint8_t i = 0;
    uint8_t *data = (uint8_t *)buffer;
    queue_input.data_len = length;
    memcpy_s(queue_input.data,sizeof(queue_input.data),buffer,length);
    osMessageQueuePut(MsgQueue_ID,&queue_input,0,0);//将数据入队
    osal_printk("[RFID] recv data length: %d\r\nrecv data: ",length);
    for(i = 0;i < length;i++)
    {
        osal_printk("%02X ",data[i]);
    }
    osal_printk("\r\n");
}

static void My_uart_pin_init(void)
{
    uapi_pin_set_mode(CONFIG_UART_RXD_PIN,PIN_MODE_1);//引脚模式设置为1
    uapi_pin_set_mode(CONFIG_UART_TXD_PIN,PIN_MODE_1);
}

static uart_buffer_config_t g_app_uart_buffer_config = {
    .rx_buffer = g_app_uart_rx_buff,
    .rx_buffer_size = UART_TRANSFER_SIZE
};

static void uart_config(void)
{
    uart_attr_t attr = {
        .baud_rate = UART_BAUDRATE,
        .data_bits = UART_DATA_8BITS,
        .stop_bits = UART_STOP_BITS,
        .parity = UART_PARITY_BIT
    };
    uart_pin_config_t pin_config = {
        .tx_pin = CONFIG_UART_TXD_PIN,
        .rx_pin = CONFIG_UART_RXD_PIN,
        .cts_pin = PIN_NONE,
        .rts_pin = PIN_NONE
    };
    uapi_uart_deinit(CONFIG_UART_BUS_ID); 
    uapi_uart_init(CONFIG_UART_BUS_ID, &pin_config, &attr, NULL, &g_app_uart_buffer_config);
}

static void *uart_task(const char *arg)
{
    unused(arg);
    My_uart_pin_init();
    uart_config();
    uapi_uart_unregister_rx_callback(CONFIG_UART_BUS_ID);
    errcode_t ret = uapi_uart_register_rx_callback(CONFIG_UART_BUS_ID,
                                                   UART_RX_CONDITION_FULL_OR_IDLE,
                                                   1, uart_rx_cbk);
    if(ret == ERRCODE_FAIL)
    {
        osal_printk("rx cbk register fail\r\n");
    }
    osal_printk("\r\n[RFID]start !\r\n");
    while(1)
    {
        if(voltage < 1760)//串联10kΩ，大概电阻为10kΩ时可以弯下门把手
        {
            pressStatus = PRESSING;
            Command_send(command_read_epc_single,sizeof(command_read_epc_single));
        }
        else
        {
            if(pressStatus == PRESSING)
            {
                uint8_t data[4] = {0xAA,0x66,0x00,0xFF};
                pressStatus = PRESSED;
                data[INDEX2] = 0xBB;
                sle_uuid_server_send_report_by_handle(data,sizeof(data));
                osal_printk("[RFID] check label\r\n");
            }
        }
        osal_msleep(1000);
    }
    
    return NULL;
}
//-------------------RFID---------------------------//

static void sle_uuid_set_base(sle_uuid_t *out)
{
    (void)memcpy_s(out->uuid, SLE_UUID_LEN, sle_uuid_base, SLE_UUID_LEN);
    out->len = UUID_LEN_2;
}

static void sle_uuid_setu2(uint16_t u2, sle_uuid_t *out)
{
    sle_uuid_set_base(out);
    out->len = UUID_LEN_2;
    encode2byte_little(&out->uuid[INDEX14], u2);
    osal_printk("[set2 check uuid RFID] : %02x %02x\r\n", out->uuid[INDEX14], out->uuid[INDEX15]);
}

static void ssaps_read_request_cbk(uint8_t server_id,
                                   uint16_t conn_id,
                                   ssaps_req_read_cb_t *read_cb_para,
                                   errcode_t status)
{
    osal_printk("[uuid server] ssaps read request cbk server_id:%x, conn_id:%x, handle:%x, status:%x\r\n", server_id,
                conn_id, read_cb_para->handle, status);
}

static void ssaps_write_request_cbk(uint8_t server_id,
                                    uint16_t conn_id,
                                    ssaps_req_write_cb_t *write_cb_para,
                                    errcode_t status)
{
    osal_printk("[uuid server] ssaps write request cbk server_id:%x, conn_id:%x, handle:%x, status:%x\r\n", server_id,
                conn_id, write_cb_para->handle, status);
    osal_printk("write request data: %s\r\n", write_cb_para->value);
    if (write_cb_para->value[INDEX0] == 0xAA && write_cb_para->value[INDEX1] == 0x33 &&
        write_cb_para->value[INDEX10] == 0xFF) {
        time_t rawtime;
        time_convert(&rawtime, &(write_cb_para->value[INDEX2]));
        struct timeval current_time;
        current_time.tv_sec = rawtime;
        current_time.tv_usec = 0;
        if (settimeofday(&current_time, NULL) == -1) {
            osal_printk("settimeofday FAIL\r\n");
            return;
        }
        osal_printk("settimeofday SUCC\r\n");
    }
}

static void ssaps_mtu_changed_cbk(uint8_t server_id, uint16_t conn_id, ssap_exchange_info_t *mtu_size, errcode_t status)
{
    osal_printk("[uuid server] ssaps write request cbk server_id:%x, conn_id:%x, mtu_size:%x, status:%x\r\n", server_id,
                conn_id, mtu_size->mtu_size, status);
}

static void ssaps_start_service_cbk(uint8_t server_id, uint16_t handle, errcode_t status)
{
    osal_printk("[uuid server] start service cbk server_id:%x, handle:%x, status:%x\r\n", server_id, handle, status);
}

static void sle_ssaps_register_cbks(void)
{
    ssaps_callbacks_t ssaps_cbk = {0};
    ssaps_cbk.start_service_cb = ssaps_start_service_cbk;
    ssaps_cbk.mtu_changed_cb = ssaps_mtu_changed_cbk;
    ssaps_cbk.read_request_cb = ssaps_read_request_cbk;
    ssaps_cbk.write_request_cb = ssaps_write_request_cbk;
    ssaps_register_callbacks(&ssaps_cbk);
}

static errcode_t sle_uuid_server_service_add(void)
{
    errcode_t ret;
    sle_uuid_t service_uuid = {0};
    sle_uuid_setu2(SLE_UUID_SERVER_SERVICE_RFID, &service_uuid);
    ret = ssaps_add_service_sync(g_server_id, &service_uuid, 1, &g_service_handle); /* 1： is primary*/
    if (ret != ERRCODE_SLE_SUCCESS) {
        osal_printk("[uuid server] sle uuid add service fail, ret:%x\r\n", ret);
        return ERRCODE_SLE_FAIL;
    }
    return ERRCODE_SLE_SUCCESS;
}

static errcode_t sle_uuid_server_property_add(void)
{
    errcode_t ret;
    ssaps_property_info_t property = {0};
    ssaps_desc_info_t descriptor = {0};
    uint8_t ntf_value[] = {0x01, 0x0};

    property.permissions = SLE_UUID_TEST_PROPERTIES;
    sle_uuid_setu2(SLE_UUID_SERVER_NTF_REPORT, &property.uuid);
    property.value = osal_vmalloc(sizeof(g_sle_property_value));
    property.operate_indication = SSAP_OPERATE_INDICATION_BIT_READ | SSAP_OPERATE_INDICATION_BIT_NOTIFY;
    if (property.value == NULL) {
        osal_printk("[uuid server] sle property mem fail\r\n");
        return ERRCODE_SLE_FAIL;
    }
    if (memcpy_s(property.value, sizeof(g_sle_property_value), g_sle_property_value, sizeof(g_sle_property_value)) !=
        EOK) {
        osal_vfree(property.value);
        osal_printk("[uuid server] sle property mem cpy fail\r\n");
        return ERRCODE_SLE_FAIL;
    }
    ret = ssaps_add_property_sync(g_server_id, g_service_handle, &property, &g_property_handle);
    if (ret != ERRCODE_SLE_SUCCESS) {
        osal_printk("[uuid server] sle uuid add property fail, ret:%x\r\n", ret);
        osal_vfree(property.value);
        return ERRCODE_SLE_FAIL;
    }
    descriptor.permissions = SLE_UUID_TEST_DESCRIPTOR;
    descriptor.operate_indication = SSAP_OPERATE_INDICATION_BIT_READ | SSAP_OPERATE_INDICATION_BIT_WRITE;
    descriptor.type = SSAP_DESCRIPTOR_USER_DESCRIPTION;
    descriptor.value_len = sizeof(ntf_value);
    descriptor.value = osal_vmalloc(sizeof(ntf_value));
    if (descriptor.value == NULL) {
        osal_printk("[uuid server] sle descriptor mem fail\r\n");
        osal_vfree(property.value);
        return ERRCODE_SLE_FAIL;
    }
    if (memcpy_s(descriptor.value, sizeof(ntf_value), ntf_value, sizeof(ntf_value)) != EOK) {
        osal_printk("[uuid server] sle descriptor mem cpy fail\r\n");
        osal_vfree(property.value);
        osal_vfree(descriptor.value);
        return ERRCODE_SLE_FAIL;
    }
    ret = ssaps_add_descriptor_sync(g_server_id, g_service_handle, g_property_handle, &descriptor);
    if (ret != ERRCODE_SLE_SUCCESS) {
        osal_printk("[uuid server] sle uuid add descriptor fail, ret:%x\r\n", ret);
        osal_vfree(property.value);
        osal_vfree(descriptor.value);
        return ERRCODE_SLE_FAIL;
    }
    osal_vfree(property.value);
    osal_vfree(descriptor.value);
    return ERRCODE_SLE_SUCCESS;
}

static errcode_t sle_uuid_server_add(void)
{
    errcode_t ret;
    sle_uuid_t app_uuid = {0};

    osal_printk("[uuid server] sle uuid add service in\r\n");
    app_uuid.len = sizeof(g_sle_uuid_app_uuid);
    if (memcpy_s(app_uuid.uuid, app_uuid.len, g_sle_uuid_app_uuid, sizeof(g_sle_uuid_app_uuid)) != EOK) {
        return ERRCODE_SLE_FAIL;
    }
    ssaps_register_server(&app_uuid, &g_server_id);

    if (sle_uuid_server_service_add() != ERRCODE_SLE_SUCCESS) {
        ssaps_unregister_server(g_server_id);
        return ERRCODE_SLE_FAIL;
    }

    if (sle_uuid_server_property_add() != ERRCODE_SLE_SUCCESS) {
        ssaps_unregister_server(g_server_id);
        return ERRCODE_SLE_FAIL;
    }
    osal_printk("[uuid server] sle uuid add service, server_id:%x, service_handle:%x, property_handle:%x\r\n",
                g_server_id, g_service_handle, g_property_handle);
    ret = ssaps_start_service(g_server_id, g_service_handle);
    if (ret != ERRCODE_SLE_SUCCESS) {
        osal_printk("[uuid server] sle uuid add service fail, ret:%x\r\n", ret);
        return ERRCODE_SLE_FAIL;
    }
    osal_printk("[uuid server] sle uuid add service out\r\n");
    return ERRCODE_SLE_SUCCESS;
}

/* device通过uuid向host发送数据：report */
errcode_t sle_uuid_server_send_report_by_uuid(const uint8_t *data, uint16_t len)
{
    ssaps_ntf_ind_by_uuid_t param = {0};
    param.type = SSAP_PROPERTY_TYPE_VALUE;
    param.start_handle = g_service_handle;
    param.end_handle = g_property_handle;
    param.value_len = len;
    param.value = osal_vmalloc(len);
    if (param.value == NULL) {
        osal_printk("[uuid server] send report new fail\r\n");
        return ERRCODE_SLE_FAIL;
    }
    if (memcpy_s(param.value, param.value_len, data, len) != EOK) {
        osal_printk("[uuid server] send input report memcpy fail\r\n");
        osal_vfree(param.value);
        return ERRCODE_SLE_FAIL;
    }
    sle_uuid_setu2(SLE_UUID_SERVER_NTF_REPORT, &param.uuid);
    ssaps_notify_indicate_by_uuid(g_server_id, g_sle_conn_hdl, &param);
    osal_vfree(param.value);
    return ERRCODE_SLE_SUCCESS;
}

/* device通过handle向host发送数据：report */
errcode_t sle_uuid_server_send_report_by_handle(const uint8_t *data, uint8_t len)
{
    ssaps_ntf_ind_t param = {0};

    param.handle = g_property_handle;
    param.type = SSAP_PROPERTY_TYPE_VALUE;
    param.value = osal_vmalloc(len);
    param.value_len = len;
    if (param.value == NULL) {
        osal_printk("[uuid server] send report new fail\r\n");
        return ERRCODE_SLE_FAIL;
    }
    if (memcpy_s(param.value, param.value_len, data, len) != EOK) {
        osal_printk("[uuid server] send input report memcpy fail\r\n");
        osal_vfree(param.value);
        return ERRCODE_SLE_FAIL;
    }
    ssaps_notify_indicate(g_server_id, g_sle_conn_hdl, &param);
    osal_vfree(param.value);
    return ERRCODE_SLE_SUCCESS;
}

static void sle_connect_state_changed_cbk(uint16_t conn_id,
                                          const sle_addr_t *addr,
                                          sle_acb_state_t conn_state,
                                          sle_pair_state_t pair_state,
                                          sle_disc_reason_t disc_reason)
{
    osal_printk(
        "[uuid server] connect state changed conn_id:0x%02x, conn_state:0x%x, pair_state:0x%x, \
        disc_reason:0x%x\r\n",
        conn_id, conn_state, pair_state, disc_reason);
    osal_printk("[uuid server] connect state changed addr:%02x:**:**:**:%02x:%02x\r\n", addr->addr[BT_INDEX_0],
                addr->addr[BT_INDEX_4], addr->addr[BT_INDEX_5]);
    g_sle_conn_hdl = conn_id;
    if (conn_state == SLE_ACB_STATE_DISCONNECTED) {
        sle_start_announce(SLE_ADV_HANDLE_DEFAULT);
    }
}

static void sle_pair_complete_cbk(uint16_t conn_id, const sle_addr_t *addr, errcode_t status)
{
    osal_printk("[uuid server] pair complete conn_id:%02x, status:%x\r\n", conn_id, status);
    osal_printk("[uuid server] pair complete addr:%02x:**:**:**:%02x:%02x\r\n", addr->addr[BT_INDEX_0],
                addr->addr[BT_INDEX_4], addr->addr[BT_INDEX_5]);
}

static void sle_conn_register_cbks(void)
{
    sle_connection_callbacks_t conn_cbks = {0};
    conn_cbks.connect_state_changed_cb = sle_connect_state_changed_cbk;
    conn_cbks.pair_complete_cb = sle_pair_complete_cbk;
    sle_connection_register_callbacks(&conn_cbks);
}

/* 初始化uuid server */
errcode_t sle_uuid_server_init(void)
{
    enable_sle();
    sle_conn_register_cbks();
    sle_ssaps_register_cbks();
    sle_uuid_server_add();
    sle_uuid_server_adv_init();
    osal_printk("[uuid server] init ok\r\n");
    return ERRCODE_SLE_SUCCESS;
}

#define SLE_UUID_SERVER_TASK_PRIO 24
#define SLE_UUID_SERVER_STACK_SIZE 0x2000
#define GET_CURRENT_TIME_PIO 28
#define GET_CURRENT_TIME_STACK_SIZE 0x1000
#define UART_TASK_PRIO                     25
#define UART_TASK_STACK_SIZE               0x1000
#define QUEUE_DEAL_TASK_PRIO               26
#define QUEUE_DEAL_TASK_SIZE               0x1000
#define ADC_TASK_PRIO 27
#define ADC_TASK_STACK_SIZE 0x1000

static void sle_uuid_server_entry(void)
{
    // 创建消息队列
    MsgQueue_ID = osMessageQueueNew(MSG_QUEUE_NUMBER, sizeof(queue_structure_t),
                                    NULL); // 消息队列中的消息个数，消息队列中的消息大小，属性
    if (MsgQueue_ID != NULL) {
        printf("ID = %d, Create MsgQueue_ID is OK!\n", MsgQueue_ID);
    }

    osal_task *task_handle = NULL;
    osal_kthread_lock();
    //sle
    task_handle = osal_kthread_create((osal_kthread_handler)sle_uuid_server_init, 0, "sle_uuid_server",
                                      SLE_UUID_SERVER_STACK_SIZE);
    if (task_handle != NULL) {
        osal_kthread_set_priority(task_handle, SLE_UUID_SERVER_TASK_PRIO);
        osal_kfree(task_handle);
    }
    //sntp
    task_handle = osal_kthread_create((osal_kthread_handler)get_current_time, 0, "get_time", GET_CURRENT_TIME_STACK_SIZE);
    if (task_handle != NULL) {
        osal_kthread_set_priority(task_handle, GET_CURRENT_TIME_PIO);
        osal_kfree(task_handle);
    }
    //uart
    task_handle = osal_kthread_create((osal_kthread_handler)uart_task, 0, "RFID Task", UART_TASK_STACK_SIZE);
    if (task_handle != NULL) {
        osal_kthread_set_priority(task_handle, UART_TASK_PRIO);
    }
    //queue
    task_handle = osal_kthread_create((osal_kthread_handler)queue_deal_task, 0, "queue_deal Task", QUEUE_DEAL_TASK_SIZE);
    if (task_handle != NULL) {
        osal_kthread_set_priority(task_handle, QUEUE_DEAL_TASK_PRIO);
    }
    //adc
    task_handle = osal_kthread_create((osal_kthread_handler)adc_task, 0, "AdcTask", ADC_TASK_STACK_SIZE);
    if (task_handle != NULL) {
        osal_kthread_set_priority(task_handle, ADC_TASK_PRIO);
    osal_kthread_unlock();
    }
}

/* Run the app entry. */
app_run(sle_uuid_server_entry);